/*
 * 语言基础
 */
pub fn base_language() {
    let x = 5;
    println!("The value of x is: {}", x);
    //x = 7; 紧接着上一句会报错
    /*
     * 变量默认是不可变的（immutable），书上的解释原文：
     * 这是推动你以充分利用 Rust 提供的安全性和简单并发性来编写代码的众多方式之一
     * 目前我仍然不明白，但是上一章有用到mut来声明可变
     * 书上推荐的是大型数据结构用可变变量，小型创建新实例。
     */
    const y: i32 = 10;
    println!(" {}", y);
    /*
     * 变量和常量的区别
     * 刚刚看到变量不可变的时候我就想怎么不叫常量？
     * 书里解释了区别：
     * 首先，不允许对常量使用 mut 。常量不光默认不可变，它总是不能变。
     * 常量声明使用 const （和C#一样），而且 必须 注明值的类型。
     * 常量可以在任何作用域声明，包括全局作用域
     * 最后一个区别是，常量只能被设置为常量表达式，而不能是函数调用的结果，或任何其他只能在运行时计算出的值。
     * 和c#一样，常量也检验用全大写命名
     */
    let x = 6;
    let x = x + 4;
    let x = "abc";
    /*
     * 隐藏（Shadowing）
     * 上面的代码是可以运行通过的，这里相当于定义了一个同名的变量，他会隐藏之前的变量
     * 隐藏变量可以发生多次。
     * 隐藏和 mut 不同，当不小心对变量重新赋值时，没有let关键字就会报错。可以用这个值计算，但是计算后的值仍然是不变的
     * 和 mut 最大的区别是，let其实创建了一个新变量，所以是可以改变类型的。有点像动态语言
     * 结论：rust是可以声明同名不同类型的变量，但是后来的变量会隐藏（我觉得覆盖更好理解）之前的变量
     */
    let number = {
        //当你需要经常改变一个变量的时候，shadowing是很好的
        let x = 5;
        let x = double_number(x);
        x //x全部操作都在本块作用域，出了这个作用域则还是上面最后一次的值
    };
    println!("{},{}", x, number); //返回 abc,10
}
fn double_number(x: i32) -> i32 {
    x * 2
}
